<?php
/***************************************************************
*  Copyright notice
*
*  (c) 2008 Christophe Monard <contact@cmonard.fr>
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

/**
 * Librairie de fonction commune aux extensions
 *
 * @author	Christophe Monard   <contact@cmonard.fr>
 *
 * Appel direct:
 *  optionnel (utilisation de l'autoloader de TYPO3) require_once(t3lib_extMgm::extPath('cmd_api').'class.tx_cmdapi.php');
 *	tx_cmdapi::*function_name*
 *
 * [CLASS/FUNCTION INDEX of SCRIPT]
 *
 *   58: class tx_cmdapi
 *   65:    function cleanTemplate($content)
 *   82:    function stripAccentsAndSpaces_doTransform($content, $spaceReplacer = '', $transform = '', $trueUTF8 = true)
 *  108:    function getCheckboxValues($table, $field, $row)
 *  127:    function getFieldsFromTable($table, $exclude = array('l10n_parent', 'l10n_diffsource'))
 *  160:	function sendMail($recipient = null, $param = array(), $debug = false)
 *  263:	function getTS($rootPid = 1, $ext = '')
 *  315:	function initEID($param, &$connected = '', &$BE_USER = '', $getTSFE = false)
 *  361:	function getCache($key, $identifier, $expTime = 0)
 *  376:	function setCache($key, $identifier, $data)
 *
 * TOTAL FUNCTIONS: 9
 *
 */

/**
 * Class permettant l'appel au fonctions
 *
 * @author	Christophe Monard <contact@cmonard.fr>
 * @package	TYPO3
 * @subpackage	tx_cmdapi
 */
class tx_cmdapi {
	/**
	 * Fonction nettoyant le code des markers non utilisé
	 * 
	 * @param	string		$content: Contenu à traiter
	 * @return	Contenu généré
	 */
	function cleanTemplate($content) {
		// on nettoie le template des marquers inutilisé
		$content = preg_replace("/###.+?###/is", '', $content);

		// on renvoie le template préparé
		return $content;
	}

	/**
	 * Fonction enlevant accent et espace et faisant une transformation en minuscule, majuscule ou capitalise
	 * 
	 * @param	string		$content: Contenu à traiter
	 * @param	string		$spaceReplacer: le caractère de substitution pour les espaces
	 * @param	string		$transform: type de transformation ('', 'lower', 'upper', 'capitalise', 'first')
	 * @param	bool		$trueUTF8: set to false if db is different from utf-8 and forceCharset = utf-8
	 * @return	Contenu généré
	 */
	function stripAccentsAndSpaces_doTransform($content, $spaceReplacer = '', $transform = '', $trueUTF8 = true) {
		$accent = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ';
		if ($trueUTF8 && $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] && $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] == 'utf-8') {
			$content = utf8_decode($content);
			$accent = utf8_decode($accent);
		}
		$content = strtr($content, $accent, 'AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn'); # do not handle utf-8 ??
		switch ($transform) {
			case 'lower': $content = strtolower($content); break;
			case 'upper': $content = strtoupper($content); break;
			case 'capitalise': $content = ucwords($content); break;
			case 'first': $content = ucfirst($content); break;
			default: break;
		}
		$content = str_replace(' ', $spaceReplacer, $content);
		return $content;
	}

	/**
	 * Fonction générant la liste des éléments cochés d'un champ de type check sous forme de tableau associatif: uid => libellé
	 * 
	 * @param	string		$table: Nom de la table
	 * @param	string		$field: Nom du champ a traiter de la table
	 * @param	array		$row: Ligne courrante de la table
	 * @return	le tableau de valeurs pour la ligne courrante ou false en cas d'erreur
	 */
	function getCheckboxValues($table, $field, $row) {
		t3lib_div::loadTCA($table);
		$checkConfig = &$TCA[$table]['columns'][$field]['config'];
		if ($checkConfig['type'] && $checkConfig['type']=='check' && ($nbChecks = count($checkConfig['items']))>0) {
			$checks = array();
			for ($x=0; $x<$nbChecks; $x++)
				if ($row[$field]&pow(2,$x))
					$checks[$row['uid']][$x] = $GLOBALS['TSFE']->sL($checkConfig['items'][$x][0]);
		} else $checks = false;
		return $checks;
	}

	/**
	 * Fonction renvoyant un tableau des champs de la table données en parametre
	 * 
	 * @param	string		$table: Nom de la table pour laquelle on souhaite récupérer les champs
	 * @param	array		$exclude: liste des champs à exclure de la récupération TCA
	 * @return	tableau des champs de la table
	 */
	function getFieldsFromTable($table, $exclude = array('l10n_parent', 'l10n_diffsource')) {
		GLOBAL $TCA;
		t3lib_div::loadTCA($table);
		$columns = &$TCA[$table]['columns'];
		$fieldList = t3lib_div::trimExplode(',', $TCA[$table]['interface']['showRecordFieldList']); // liste des champs de la table

		$return = array();
		foreach ($fieldList as $field)
			if (!in_array($field, $exclude))
				$return[] = $field;
		return $return;
	}

	/**
	 * Mailing function
	 * 
	 * @param	string		$recipient: Mail recipient(s) (eg@eg.com | example <eg@eg.com> | eg1@eg.com, eg2@eg.com | ...)
	 *							// For TYPO3 < 4.5 only, null otherwise
	 * @param	array		$param: Array of configuration of the mail
	 *							// For TYPO3 >= 4.5 (to, cc, bcc, sender, from, reply, return_path, priority, read_receipt, subject, body, embed, files)
	 *								// sender format : array('email' => validEmail[, 'name' => name])
	 *								// to, cc, bcc, from, reply format : array(name => validEmail[, validEmail[, ...]])
	 *								// return_path, read_receipt : string validEmail
	 *								// priority : integer 1 => 'Highest', 2 => 'High', 3 => 'Normal', 4 => 'Low', 5 => 'Lowest'
	 *								// subject : string
	 *								// body : array('text' => string[, 'format' => 'text/html'])
	 *								// embed, files : array(newFileName => filePathAndName[, filePathAndName[, ...]]) - for embed newFileName will not be used
	 *							// For TYPO3 < 4.5 (organisation, from_name, replyto_name, from_email, replyto_email, subject, bodyPlain, bodyHtml, forceReturnPath, files)
	 * @param	bool		$debug: For TYPO3 < 4.5 : If true, make mail preview, not sent
	 * @return	false when missing parameters, otherwise
	 *							// For TYPO3 >= 4.5 array of result (sent, fail)
	 *							// For TYPO3 < 4.5 send mail result
	 */
	function sendMail($recipient = null, $param = array(), $debug = false) {
		if (t3lib_div::int_from_ver(TYPO3_version) >= 4005000) { // TYPO3 4.5 and more
			if (count($param > 0) && isset($param['to']) && isset($param['body'])) {
				$mail = t3lib_div::makeInstance('t3lib_mail_Message');
				// To
				foreach ((array)$param['to'] as $to_name => $to_email)
					$mail->addTo($to_email, (!is_numeric($to_name)?$to_name:null));
				// CC
				if (isset($param['cc']))
					foreach ((array)$param['cc'] as $cc_name => $cc_email)
						$mail->addCc($cc_email, (!is_numeric($cc_name)?$cc_name:null));
				// BCC
				if (isset($param['bcc']))
					foreach ((array)$param['bcc'] as $bcc_name => $bcc_email)
						$mail->addBcc($bcc_email, (!is_numeric($bcc_name)?$bcc_name:null));
				// Sender
				if (isset($param['sender']) && $param['sender']['email'])
					$mail->setSender($param['sender']['email'], (isset($param['sender']['name'])?$param['sender']['name']:null));
				// From
				if (isset($param['from']))
					foreach ((array)$param['from'] as $from_name => $from_email)
						$mail->addFrom($from_email, (!is_numeric($from_name)?$from_name:null));
				// Reply To
				if (isset($param['reply']))
					foreach ((array)$param['reply'] as $reply_name => $reply_email)
						$mail->addReplyTo($reply_email, (!is_numeric($reply_name)?$reply_name:null));
				// Return Path
				if (isset($param['return_path']))
					$mail->setReturnPath($param['return_path']);
				// Priority
				if (isset($param['priority']))
					$mail->setPriority(intval($param['priority']));
				// readReceiptTo
				if (isset($param['read_receipt']))
					$mail->setReadReceiptTo($param['read_receipt']);
				// Subject
				if (isset($param['subject']))
					$mail->setSubject($param['subject']);
				// Bodytext
				$mail->setBody($param['body']['text'], (isset($param['body']['format'])?$param['body']['format']:'text/html'));
				if (!isset($param['body']['format']) || $param['body']['format'] == 'text/html')
					$mail->addPart(strip_tags($param['body']['text']), 'text/plain');
				// Embed files
				if ($param['embed'])
					foreach ((array)$param['embed'] as $file)
						$mail->embed(Swift_Attachment::fromPath($file));
				// Files
				if ($param['files'])
					foreach ((array)$param['files'] as $name => $file)
						if (is_numeric($name)) $mail->attach(Swift_Attachment::fromPath($file));
						else $mail->attach(Swift_Attachment::fromPath($file)->setFilename($name));
				// Send the mail !
				$sent = $mail->send();
				// Failled send
				$fail = $mail->getFailedRecipients();
				// Return the array of result
				return array('sent' => $sent, 'fail' => $fail);
			} else return false;
		} else { // old method still working for compatibility
			if ($recipient != '' && count($param > 0)) {
				$mailer=t3lib_div::makeInstance('t3lib_htmlmail');
				$mailer->start();
				$mailer->use8Bit();
				$mailer->organisation = $param['organisation']?$param['organisation']:'';
				$mailer->from_name =  $param['from_name']?$param['from_name']:'';
				$mailer->replyto_name = $param['replyto_name']?$param['replyto_name']:'';
				$mailer->from_email = $param['from_email']?$param['from_email']:'';
				$mailer->replyto_email = $param['replyto_email']?$param['replyto_email']:'';
				$mailer->subject = $param['subject']?$param['subject']:'';
				$mailer->recipient = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']=='utf-8'?utf8_decode($recipient):$recipient;
				if ($param['forceReturnPath']) {
					$mailer->forceReturnPath = 1;
					$mailer->returnPath = $param['replyto_email']?$param['replyto_email']:($param['from_email']?$param['from_email']:'');
				}

				//pour des raison de fonctionnalité et pour être sur du résultat on fait un decode du html entity
				$bodyPLAIN = $param['bodyPlain']?html_entity_decode($param['bodyPlain'], ENT_COMPAT, ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']=='utf-8'?'UTF-8':'')):'';
				$bodyHTML = $param['bodyHtml']?$param['bodyHtml']:'';
				if ($bodyPLAIN != '') $mailer->setPlain($mailer->encodeMsg($bodyPLAIN));
				if ($bodyHTML != '') $mailer->setHtml($mailer->encodeMsg($bodyHTML));

				//ajout des fichiers
				if ($param['files'] && is_array($param['files']))
					foreach ($param['files'] as $file)
						$mailer->addAttachment(PATH_site.$file);

				$mailer->setHeaders();
				$mailer->setContent();

				if ($debug) $mailer->preview();
				else return $mailer->sendTheMail();
			} else return false;
		}
	}

	/**
	 * Fonction générant et renvoyant le code typoscript d'une page données (utile pour un cron ou un eID)
	 * 
	 * @param	int			$rootPid: pid de la page dont on doit récupérer le typoscript (1 par default)
	 * @param	array		$ext: si spécifié ne retourne que le typoscript de cette extension
	 * @param	bool		$useCache: spécifie si on doit utiliser le cache de typo3
	 * @return	le tableau de typoscript généré
	 */
	function getTS($rootPid = 1, $ext = '', $useCache = true) {
		//gestion du cache typo3
		if ($useCache) {
			$key = $rootPid.'-'.($ext!=''?$ext:'all'); // clé a utilisé pour le cache
			$cached = tx_cmdapi::getCache($key, 'getTS');
			if ($cached) return unserialize($cached);
		}

		//require des php de base
		require_once(PATH_t3lib.'class.t3lib_page.php');
		require_once(PATH_t3lib.'class.t3lib_tsparser_ext.php'); 

		//déclaration des objets necessaire
		$sysPageObj = t3lib_div::makeInstance('t3lib_pageSelect');
		$monTSObj = t3lib_div::makeInstance('t3lib_tsparser_ext');

		//génération de la config
		$sysPageObj->init(true);
		$sysPageObj->getPage($rootPid);
		$rootLine = $sysPageObj->getRootLine($rootPid);   // ID de la page que l'on désire traiter
		$monTSObj->init();
		$monTSObj->runThroughTemplates($rootLine);
		$monTSObj->generateConfig();

		//Récup du setup
		$setup = $monTSObj->setup;

		//destruction des variables et objets
		unset($monTSObj) ;
		unset($rootLine);
		unset($sysPageObj);

		//si on a spécifié une clef plugin et qu'elle existe
		if ($ext != '' && isset($setup['plugin.'][$ext.'.']))
			$setup = $setup['plugin.'][$ext.'.'];

		//mise en cache si necessaire
		if ($useCache) tx_cmdapi::setCache($key, 'getTS', $setup);

		//Envoie de la conf TS
		return $setup;
	}

	/**
	 * Fonction Initialisant les différente partie necessaire de l'eID
	 * 
	 * @param	array		$param: Tableau des instanciations à effectuer bool(lang, db, fe_user, be_user, tca), string(setLang), mixed(tca_ext)
	 * @param	object		$connected: objet du fe_user connecté à récupérer à l'appel de la fonction
	 * @param	object		$BE_USER: objet du be_user connecté à récupérer à l'appel de la fonction
	 * @param	bool		$getTSFE: should TSFE get returned
	 * @return	mixed : true or TSFE object
	 */
	function initEID($param, &$connected = '', &$BE_USER = '', $getTSFE = false) {
		if ($param['lang']) tslib_eidtools::initLanguage(($param['setLang']?$param['setLang']:'default'));
		if ($param['db']) tslib_eidtools::connectDB();
		if ($param['fe_user']) $connected = tslib_eidtools::initFeUser();
		if ($param['be_user']) {
			$BE_USER='';
			if ($_COOKIE['be_typo_user']) { // If the backend cookie is set, we proceed and checks if a backend user is logged in.
				require_once (PATH_t3lib.'class.t3lib_befunc.php');
				require_once (PATH_t3lib.'class.t3lib_userauthgroup.php');
				require_once (PATH_t3lib.'class.t3lib_beuserauth.php');
				require_once (PATH_t3lib.'class.t3lib_tsfebeuserauth.php');
			 
				// the value this->formfield_status is set to empty in order to disable login-attempts to the backend account through this script
				$BE_USER = t3lib_div::makeInstance('t3lib_tsfeBeUserAuth'); // New backend user object
				$BE_USER->OS = TYPO3_OS;
				$BE_USER->lockIP = $TYPO3_CONF_VARS['BE']['lockIP'];
				$BE_USER->start();  // Object is initialized
				$BE_USER->unpack_uc('');
				if ($BE_USER->user['uid'])  {
					$BE_USER->fetchGroupData();
					$TSFE->beUserLogin = 1;
				}
				// Now we need to do some additional checks for IP/SSL
				if (!$BE_USER->checkLockToIP() || !$BE_USER->checkBackendAccessSettingsFromInitPhp()) {
					// Unset the user initialization.
					$BE_USER='';
					$TSFE->beUserLogin=0;
				}
			}
		}
		if ($param['tca']) tslib_eidtools::initTCA();
		if ($param['tca_ext'])
			foreach ((array)$param['tca_ext'] as $ext)
				if (t3lib_extMgm::isLoaded($ext))
					tslib_eidtools::initExtensionTCA($ext);
		return ($getTSFE?tslib_eidtools::getTSFE():true);
	}

	/**
	 * Récupère l'entrée en cache
	 * 
	 * @param	string		$key clé du cache
	 * @param	string		$identifier identifiant unique (nom de fonction par exemple)
	 * @param	integer		$expTime maximum lifetime of the cache
	 * @return string l'entrée en cache sérialisé
	 */
	function getCache($key, $identifier, $expTime = 0) {
		if ($GLOBALS['TSFE']->no_cache) return;
		require_once(PATH_t3lib.'class.t3lib_page.php');
		$cacheHash = md5('tx_cmdapi-' . $identifier . $key);
		return t3lib_pageSelect::getHash($cacheHash, intval($expTime));
	}

	/**
	 * Stores data in cache
	 *
	 * @param string $key cache key
	 * @param string $identifier unique identifier
	 * @param array $data your data to store in cache
	 * @return	void
	 */
	function setCache($key, $identifier, $data) {
		if ($GLOBALS['TSFE']->no_cache) return;
		require_once(PATH_t3lib.'class.t3lib_page.php');
		$cacheIdentifier = 'tx_cmdapi-' . $identifier;
		$cacheHash = md5($cacheIdentifier . $key);
		t3lib_pageSelect::storeHash($cacheHash, serialize($data), $cacheIdentifier);
	}
}

if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cmd_api/class.tx_cmdapi.php'])	{
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cmd_api/class.tx_cmdapi.php']);
}
?>